package kmeans.bean;


import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import kmeans.exception.WXKmeansException;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.text.DecimalFormat;

public class WXKmeansData implements WritableComparable<WXKmeansData> {
    private Text kMeansText=new Text();
    private IntWritable dataSize=new IntWritable();

    public WXKmeansData() {
//        set(new Text(), new IntWritable(0));
        System.out.println("********************");
    }

    public WXKmeansData(Text kMeansText, IntWritable dataSize) {
        this.kMeansText = kMeansText;
        this.dataSize = dataSize;
    }

    public int compareTo(WXKmeansData o) {
        if (this.kMeansText.compareTo(o.kMeansText) == 0 && this.dataSize.compareTo(o.dataSize) == 0) {
            return 0;
        }
        return 1;
    }

    private void set(Text kMeansText, IntWritable dataSize) {
        this.kMeansText = kMeansText;
        this.dataSize = dataSize;
    }

    public void write(DataOutput dataOutput) throws IOException {
        kMeansText.write(dataOutput);
        dataSize.write(dataOutput);
    }

    public void readFields(DataInput dataInput) throws IOException {
        kMeansText.readFields(dataInput);
        dataSize.readFields(dataInput);
    }

    public Text getkMeansText() {
        return kMeansText;
    }

    public void setkMeansText(Text kMeansText) {
        this.kMeansText = kMeansText;
    }

    public IntWritable getDataSize() {
        return dataSize;
    }

    public void setDataSize(IntWritable dataSize) {
        this.dataSize = dataSize;
    }

    public static WXKmeansData add(WXKmeansData centroid, WXKmeansData data, int dimension) throws WXKmeansException {

        String[] newdv = data.getkMeansText().toString().trim().split(" ");
        String[] thisdv = centroid.getkMeansText().toString().trim().split(" ");
        if (newdv.length != dimension || thisdv.length != dimension) {
            throw new WXKmeansException("维度的问题");
        }
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < dimension; i++) {
            double a = Double.parseDouble(newdv[i]) + Double.parseDouble(thisdv[i]);
            DecimalFormat df = new DecimalFormat("0.00");
            result.append(df.format(a)).append(" ");
        }
        System.out.println(result);
        WXKmeansData returndata = new WXKmeansData(new Text(result.toString().trim()), new IntWritable(centroid.getDataSize().get() + data.getDataSize().get()));
        return returndata;
    }

    public void add(WXKmeansData data, int dimension) throws WXKmeansException {
        Text newData = data.kMeansText;
        String[] newStrings = newData.toString().trim().split(" ");
        String[] strings = kMeansText.toString().trim().split(" ");
        if (newStrings.length != dimension || strings.length != dimension) {
            throw new WXKmeansException("Dimension Error");
        }

        StringBuffer result = new StringBuffer();

        for (int i = 0; i < dimension; i++) {
            double a = Double.parseDouble(newStrings[i]) + Double.parseDouble(strings[i]);
            DecimalFormat df = new DecimalFormat("0.00");
            result.append(df.format(a)).append(" ");
        }

        String r = result.toString().trim();
//        System.out.println(r);
        this.kMeansText.set(r.substring(0, r.length() - 1));
        this.dataSize.set(this.dataSize.get() + data.dataSize.get());
    }

    public String getNewCentroids() {
        StringBuffer r = new StringBuffer();
        String[] strings = kMeansText.toString().trim().split(" ");
        for (String s : strings) {
            double d = Double.parseDouble(s) / dataSize.get();
            DecimalFormat df = new DecimalFormat("0.00");
            r.append(df.format(d)).append(" ");
        }

        return r.toString().trim();
    }
}
